package com.watchme.parser.utils;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.objdetect.CascadeClassifier;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;

/**
 * Created by wangqiang on 2017/10/19.
 */
public class OpenCVUtil {

    private static OpenCVUtil instance = null;

    private OpenCVUtil() {
    }

    private static Integer LOCK = 0;

    public static OpenCVUtil getInstance() {
        synchronized (LOCK) {
            if (instance == null) {
                instance = new OpenCVUtil();
            }
            return instance;
        }
    }


    public boolean isFace(String imagePath, String tempPath) {
        boolean result = false;

        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

        String xmlfilePath = this.getClass().getResource("haarcascade_frontalface_alt.xml").getPath().substring(1);
        File file = new File(xmlfilePath);
        if (!file.exists()) {
            System.out.println("not this file");
            return result;
        }

        // 创建目录
        // 如果sPath不以文件分隔符结尾，自动添加文件分隔符
        if (!tempPath.endsWith(File.separator)) {
            tempPath = tempPath + File.separator;
        }
        String dirPath = tempPath + "tmp";

        CascadeClassifier faceDetector = new CascadeClassifier();
        boolean isLoad = faceDetector.load(xmlfilePath);
        if (isLoad) {
            long now = System.currentTimeMillis();
            //创建临时文件
            try {
                String tmpFile = FileUtil.createTempFile("mytempfile", ".jpg", dirPath);
                copyImage(imagePath, tmpFile);

                int[] imgRect = new int[2];
                try {
                    imgRect = getImageWidth(tmpFile);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                int minX = imgRect[0] / 5;
                int minY = imgRect[1] / 5;
                int maxX = imgRect[0] / 2;
                int maxY = imgRect[1] / 2;

                Mat image = Imgcodecs.imread(tmpFile);
                // Detect faces in the image.
                // MatOfRect is a special container class for Rect.
                MatOfRect faceDetections = new MatOfRect();
                Size minSize = new Size(minX, minY);
                Size maxSize = new Size(maxX, maxY);
                faceDetector.detectMultiScale(image, faceDetections, 1.1f, 3, 0, minSize, maxSize);
                //faceDetector.detectMultiScale(image, faceDetections);
                //System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));
                if (faceDetections.toArray().length > 0) {
                    result = true;
                }

                long s = System.currentTimeMillis() - now;
                System.out.println("OPENCV识别人脸" + faceDetections.toArray().length + ",耗时：" + s);
            } finally {
                //关闭临时文件
                //File htmlFile = new File(tmpFile);
                //htmlFile.deleteOnExit();//程序退出时删除临时文件
            }

        } else {
            System.out.println("加载特征分类器失败！");
        }
        return result;

    }


    private void grayImage(String fileName, String destFile) {
        File file = new File(fileName);
        BufferedImage image = null;
        try {
            image = ImageIO.read(file);
        } catch (IOException e) {
            e.printStackTrace();
        }

        int width = image.getWidth();
        int height = image.getHeight();

        BufferedImage grayImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);//重点，技巧在这个参数BufferedImage.TYPE_BYTE_GRAY
        for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {
                int rgb = image.getRGB(i, j);
                grayImage.setRGB(i, j, rgb);
            }
        }

        File newFile = new File(destFile);
        try {
            ImageIO.write(grayImage, "jpg", newFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void copyImage(String src, String target) {
        File srcFile = new File(src);
        File targetFile = new File(target);
        try {
            InputStream in = new FileInputStream(srcFile);
            OutputStream out = new FileOutputStream(targetFile);
            byte[] bytes = new byte[1024];
            int len = -1;
            while ((len = in.read(bytes)) != -1) {
                out.write(bytes, 0, len);
            }
            in.close();
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }


    }


    private int[] getImageWidth(String fileName) throws IOException {
        File picture = new File(fileName);
        BufferedImage sourceImg = ImageIO.read(new FileInputStream(picture));
        int[] imgRect = new int[2];
        imgRect[0] = sourceImg.getWidth();
        imgRect[1] = sourceImg.getHeight();
        return imgRect;
    }


//    public static void main(String[] args) {
//
//        String image = "D:\\证件-4.jpg";
//        System.out.println(OpenCVUtil.getInstance().isFace(image, "D:\\"));
//
//    }
}
